home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / xlib / yakems11 / yakems.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-04  |  6.4 KB  |  252 lines

  1. #include "yakems.h"
  2. #include "mem.h"
  3. #include "iostream.h"
  4.  
  5. word emsBlock::wPageFrame = NULL;
  6. pyList emsBlock::LBlockList;
  7. int emsBlock::iCurrentHandle = 0;
  8.  
  9. void emsData::deAllocate()
  10. {
  11. //#ifndef NDEBUG
  12. //    cerr << "\nNow Deallocating " << this << ": pbDataPtr = " << pbDataPtr << ", handle = " << iHandle << ", size = " << wSize;
  13. //#endif
  14.     if (iHandle)
  15.     {
  16.         ptListIterator<emsBlock> tIBlockIterator(emsBlock::LBlockList);
  17.         while ((int)tIBlockIterator && (iHandle != tIBlockIterator.ptCurrent()->iHandle))
  18.             ++tIBlockIterator; //find the block we're in
  19.         if ((int)tIBlockIterator)
  20.         {
  21.             ptListIterator<emsData> tIDataIterator(tIBlockIterator.ptCurrent()->LDataList);
  22.             while ((int)tIDataIterator && (this != tIDataIterator.ptCurrent()))
  23.                 ++tIDataIterator;
  24.             if ((int)tIDataIterator && (int)tIBlockIterator)
  25.             {
  26.             tIDataIterator.pnThisNode->pnPrev->pnNext = tIDataIterator.pnThisNode->pnNext;
  27.             tIDataIterator.pnThisNode->pnNext->pnPrev = tIDataIterator.pnThisNode->pnPrev;
  28.             }
  29.         }
  30.     }
  31. //    else if (pbDataPtr)
  32. //        delete pbDataPtr;
  33.     pbDataPtr = NULL;
  34.     iHandle = 0;
  35.     wSize = 0;
  36. }
  37. emsData::emsData()
  38. {
  39. //#ifndef NDEBUG
  40. //    cerr << "\nCreating new emsData block " << this;
  41. //#endif
  42.     pbDataPtr = NULL;
  43.     iHandle = 0;
  44.     wSize = 0;
  45. };
  46.  
  47. emsData::~emsData() //this is a pain; it must be removed from the list first.
  48. {
  49. //#ifndef NDEBUG
  50. //    cerr << "\nNow Destroying " << this;
  51. //#endif
  52.     deAllocate();
  53. }
  54.  
  55. byte * emsData::pbUseData(void * dataToUse, word wSizeMoved)
  56. {
  57.     pbData();
  58.     if (pbDataPtr && (wSizeMoved <= wSize))
  59.     {
  60.         memcpy(pbDataPtr, dataToUse, wSize);
  61.         return pbDataPtr;
  62.     }
  63.     else
  64.         return NULL;
  65. }
  66.  
  67. byte * emsData::pbAllocate(word wSizeToAllocate)
  68. {
  69. //#ifndef NDEBUG
  70. //    cerr << "\nNow Allocating " << wSizeToAllocate << " bytes for " << this;
  71. //#endif
  72.     if (pbDataPtr)
  73.         deAllocate();
  74.     if (wSizeToAllocate == 0)
  75.     {
  76.         wSize = 0;
  77.         pbDataPtr = NULL;
  78.         iHandle = 0;
  79.         return pbDataPtr;
  80.     }
  81.     ASSERT(wSizeToAllocate > 0);
  82.     ptListIterator<emsBlock> tIBlockIterator(emsBlock::LBlockList);
  83.     emsBlock * myBlock = NULL;
  84.     if (emsBlock::wPageFrame)
  85.     {
  86.         while ((int)tIBlockIterator)
  87.         {
  88.             ptListIterator<emsData> tIDataIterator(tIBlockIterator.ptCurrent()->LDataList);
  89.             word startLoc = 0, endLoc = 0;
  90.             while((int)tIDataIterator)
  91.             {
  92.                 startLoc = (FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr) + tIDataIterator.ptCurrent()->wSize); //the location of this block
  93.                 if (tIDataIterator.pnThisNode->pnNext == &(tIBlockIterator.ptCurrent()->LDataList.nTail))
  94.                     endLoc = 65535;
  95.                 else
  96.                     endLoc = FP_OFF(((emsData *)(tIDataIterator.pnThisNode->pnNext->pyData))->pbDataPtr);
  97.                 if ((endLoc - startLoc) >= wSizeToAllocate)
  98.                 {
  99.                     myBlock = ((emsBlock *)tIBlockIterator.ptCurrent());
  100.                     myBlock->LDataList.addNode(new pyListNode(this, tIDataIterator.pnThisNode->pnNext));
  101.                     iHandle = myBlock->iHandle;
  102.                     pbDataPtr = (byte *)MK_FP(emsBlock::wPageFrame, startLoc);
  103.                     wSize = wSizeToAllocate;
  104.                     if (iHandle)
  105.                     return pbDataPtr;
  106.                 }
  107.                 ++tIDataIterator;
  108.             }
  109.             ++tIBlockIterator;
  110.         }
  111.         if (!myBlock)
  112.         {
  113.             myBlock = new emsBlock;
  114.             myBlock->bIsTemporary = 1;
  115.             emsBlock::LBlockList.addTail(myBlock);
  116.         }
  117.         if (myBlock && (myBlock->iHandle)) //it's a new block, in other words
  118.         {
  119.             iHandle = myBlock->iHandle;
  120.             pbDataPtr = (byte *)MK_FP(emsBlock::wPageFrame, 0);
  121.             wSize = wSizeToAllocate;
  122.             myBlock->LDataList.addTail(this);
  123.         }
  124.         else
  125.             emsBlock::LBlockList.removeTail();
  126.     }
  127.     if (!pbDataPtr)
  128.     {
  129.         iHandle = 0;
  130.         pbDataPtr = new byte[wSize = wSizeToAllocate];
  131.     }
  132.     if (iHandle)
  133.         ASSERT(((long)FP_OFF(pbDataPtr) + (long)wSize) < (long)65535);
  134.     return pbDataPtr;
  135. }
  136.  
  137. byte * emsData::pbData(void)
  138. {
  139.     if (iHandle)
  140. //    if (iHandle && (iHandle!=emsBlock::iCurrentHandle))
  141.     {
  142.         wEms_map(0, iHandle, 0);
  143.         wEms_map(1, iHandle, 1);
  144.         wEms_map(2, iHandle, 2);
  145.         wEms_map(3, iHandle, 3);
  146.         emsBlock::iCurrentHandle = iHandle;
  147.     }
  148.     if (iHandle)
  149.         ASSERT(FP_SEG(pbDataPtr) == emsBlock::wPageFrame);
  150.     return pbDataPtr;
  151. };
  152.  
  153. word emsBlock::wInit(void)
  154. {
  155.     if (wEms_verify())
  156.     {
  157.         wPageFrame = wEms_getframe();
  158.         return 1;
  159.     }
  160.     else
  161.     {
  162.         wPageFrame = 0;
  163.         return 0;
  164.   }
  165. };
  166.  
  167. emsBlock::emsBlock(void)
  168. {
  169.     iHandle = wEms_alloc(4);
  170. }
  171.  
  172. //frees a handle
  173. emsBlock::~emsBlock(void)
  174. {
  175.     LDataList.pyList::~pyList();
  176.     if (iHandle)
  177.         wEms_free(iHandle);
  178. }
  179.  
  180.  
  181. //emsBlock::swapIn swaps in all four pages of an emsBlock in turn and
  182. //resets the current handle.
  183. void emsBlock::swapIn(void)
  184. {
  185.     wEms_map(0, iHandle, 0);
  186.     wEms_map(1, iHandle, 1);
  187.     wEms_map(2, iHandle, 2);
  188.     wEms_map(3, iHandle, 3);
  189.     iCurrentHandle = iHandle;
  190. }
  191.  
  192. //emsBlock::defragment steps through every emsData entry in an emsBlock
  193. //and moves it up in the block until all free spaces are filled.
  194. //pointers in the emsData blocks are updated to include the new information.
  195.  
  196. void emsBlock::defragment(void)
  197. {
  198.     swapIn();
  199.     word wLastData = 0;
  200.     ptListIterator<emsData> tIDataIterator(LDataList);
  201.     while((int)tIDataIterator)
  202.     {
  203.         if (wLastData < FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr))
  204.         {
  205.             memmove(MK_FP(wPageFrame, wLastData),
  206.                             MK_FP(wPageFrame, FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr)),
  207.                             tIDataIterator.ptCurrent()->wSize);
  208.             tIDataIterator.ptCurrent()->pbDataPtr = (byte *)MK_FP(wPageFrame, wLastData);
  209.  
  210.         }
  211.         wLastData += tIDataIterator.ptCurrent()->wSize;
  212.         ++tIDataIterator;
  213.     }
  214. }
  215.  
  216. //emsBlock::defragmentAllEMS steps through every block of EMS allocated
  217. //and defragments it in turn.
  218.  
  219. void emsBlock::defragmentAllEMS(void)
  220. {
  221.     ptListIterator<emsBlock> tIBlockIterator(LBlockList);
  222.     while((int)tIBlockIterator)
  223.     {
  224.         tIBlockIterator.ptCurrent()->defragment();
  225.         ++tIBlockIterator;
  226.     }
  227. }
  228.  
  229.  
  230. void emsBlock::showBlockStatus()
  231. {
  232.     ptListIterator<emsBlock> tIBlockIterator(emsBlock::LBlockList);
  233.     while((int)tIBlockIterator)
  234.     {
  235.         cout << "\nNew Block: Handle = " << tIBlockIterator.ptCurrent()->iHandle << ":\n";
  236.         ptListIterator<emsData> tIDataIterator(tIBlockIterator.ptCurrent()->LDataList);
  237.         while((int)tIDataIterator)
  238.         {
  239.             cout << "   Data block-- start: " << FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr);
  240.             cout << "\t  end: " << FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr) + tIDataIterator.ptCurrent()->wSize - 1;
  241.             cout << "\t  size: " << tIDataIterator.ptCurrent()->wSize << "\n";
  242.             ++tIDataIterator;
  243.         }
  244.         ++tIBlockIterator;
  245.     }
  246. }
  247.  
  248. void emsBlock::freeAllEMS()
  249. {
  250.     while (!LBlockList.iIsEmpty())
  251.         LBlockList.removeTail();
  252. }